package com.fuyun.rpc.client.monitor;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * RPC调用指标收集器
 */
@Slf4j
@Component
public class MetricsCollector {

	private static MeterRegistry meterRegistry;

	private static final AtomicInteger ACTIVE_CONNECTIONS = new AtomicInteger(0);
	private static final AtomicInteger IDLE_CONNECTIONS = new AtomicInteger(0);

	@Autowired
	public void setMeterRegistry(MeterRegistry meterRegistry) {
		MetricsCollector.meterRegistry = meterRegistry;

		// 注册gauge指标
		if (meterRegistry != null) {
			meterRegistry.gauge("rpc.connection.pool.active", ACTIVE_CONNECTIONS);
			meterRegistry.gauge("rpc.connection.pool.idle", IDLE_CONNECTIONS);
		}
	}

	/**
	 * 记录RPC调用成功指标
	 *
	 * @param serviceName 服务名称
	 * @param methodName  方法名称
	 * @param duration    调用耗时(毫秒)
	 */
	public static void recordSuccess(String serviceName, String methodName, long duration) {
		if (meterRegistry != null) {
			Timer.Sample sample = Timer.start(meterRegistry);
			sample.stop(Timer.builder("rpc.call.duration")
				            .tag("service", serviceName)
				            .tag("method", methodName)
				            .tag("status", "success")
				            .register(meterRegistry));

			meterRegistry.counter("rpc.call.count", "service", serviceName, "method", methodName, "status", "success")
				.increment();
		}
	}

	/**
	 * 记录RPC调用失败指标
	 *
	 * @param serviceName 服务名称
	 * @param methodName  方法名称
	 * @param duration    调用耗时(毫秒)
	 * @param exception   异常类型
	 */
	public static void recordFailure(String serviceName, String methodName, long duration, String exception) {
		if (meterRegistry != null) {
			Timer.Sample sample = Timer.start(meterRegistry);
			sample.stop(Timer.builder("rpc.call.duration")
				            .tag("service", serviceName)
				            .tag("method", methodName)
				            .tag("status", "failure")
				            .tag("exception", exception)
				            .register(meterRegistry));

			meterRegistry.counter("rpc.call.count", "service", serviceName, "method", methodName, "status", "failure",
			                      "exception", exception)
				.increment();
		}
	}

	/**
	 * 记录连接池指标
	 *
	 * @param poolName 连接池名称
	 * @param active   活跃连接数
	 * @param idle     空闲连接数
	 */
	public static void recordConnectionPool(String poolName, int active, int idle) {
		// 更新原子计数器的值
		ACTIVE_CONNECTIONS.set(active);
		IDLE_CONNECTIONS.set(idle);
	}
}